import Hero from "../hero";
import {utils} from "../utils/utils";
import GameBoard from "../game/gameboard";
import AiScript from "../ai-script";
import {MAP_CONFIG, PORTAL_POINTS} from "../config/config";
import {GameVar} from "../game/GameVar";
import {model} from "../web/model/Model";

export class HeroFactory {
  private heroPrefab: cc.Prefab = null;
  private _heroPool: cc.NodePool;

  public init(prefab: cc.Prefab) {
    this.heroPrefab = prefab;
    this.initHeroes();
  }

  public createMyHero(gameboard: GameBoard) {
    const hero = gameboard.hero;
    const heroScript: Hero = hero.getComponent(Hero);
    heroScript.enabled = true;
    heroScript.score = 0
    heroScript.kill = 0
    heroScript.beKill = 0;
    heroScript.updateController = gameboard.updateController;
    heroScript.gameBoard = gameboard;
    heroScript.user.username = GameVar.userInfo.nick;
    heroScript.user.uid = GameVar.userInfo.uid;
    GameVar.myHero = heroScript;
    heroScript.user.swimId = (model.user.activeSwim % 5000);
    heroScript.user.roleId = (model.user.activeRole % 6000);
    return hero
  }

  private createHero(gameboard: GameBoard) {
    let hero = null
    if (this._heroPool.size() > 0) {
      hero = this._heroPool.get()
    } else {
      hero = cc.instantiate(this.heroPrefab);
    }
    const heroScript: Hero = hero.getComponent(Hero)
    heroScript.gameBoard = gameboard;
    heroScript.enabled = true;
    heroScript.score = 0
    heroScript.kill = 0
    heroScript.beKill = 0;
    heroScript.updateController = gameboard.updateController;
    hero.parent = gameboard.node.getChildByName('players');
    heroScript.reborn();
    return hero;
  }

  public createAI(gameboard: GameBoard, aiConfig): Hero {
    const hero = this.createHero(gameboard);
    if (!hero.getComponent(AiScript)) {
      hero.addComponent(AiScript);
    }
    const aiScript = hero.getComponent(AiScript)
    aiScript.currentAiConfig = aiConfig
    const heroScript: Hero = hero.getComponent(Hero)
    heroScript.user.username = utils.randomName();
    heroScript.user.uid = Math.floor(Math.random() * 10000);
    heroScript.user.roleId = Math.ceil(Math.random() * 4)
    heroScript.user.swimId = Math.ceil(Math.random() * 4)
    return heroScript;
  }

  private initHeroes() {
    this._heroPool = new cc.NodePool();
    for (let i = 0; i < 7; i++) {
      const ai = cc.instantiate(this.heroPrefab)
      this._heroPool.put(ai)
    }
  }

  randomPos(hero: cc.Node) {
    hero.x = Math.floor(MAP_CONFIG.startx + MAP_CONFIG.width * Math.random())
    hero.y = Math.floor(MAP_CONFIG.starty + MAP_CONFIG.height * Math.random())

    for (let i = 0; i < PORTAL_POINTS.length; i++) {
      const point = PORTAL_POINTS[i];
      if (cc.Intersection.pointInPolygon(hero.position, [cc.v2(point.x + 45, point.y + 45), cc.v2(point.x + 45, point.y - 45), cc.v2(point.x - 45, point.y + 45), cc.v2(point.x - 45, point.y - 45)])) {
        hero.x += 100;
      }
    }
  }

  recycleHero(hero: cc.Node) {
    hero.parent = null;
    this._heroPool.put(hero)
  }
}

export const heroFactory = new HeroFactory();